home *** CD-ROM | disk | FTP | other *** search
/ HyperLib 1997 Winter - Disc 1 / HYPERLIB-1997-Winter-CD1.ISO.7z / HYPERLIB-1997-Winter-CD1.ISO / オンラインウェア / UTIL / TouchMe 1.1.1.sit / touchMe 1.11 Folder / CW9 PP source / source / CTouchMeDialogDD.cp < prev    next >
Text File  |  1996-08-08  |  11KB  |  404 lines

  1. // ==================================================
  2. //    CTouchMeDialogDD.cp
  3. //    Copyright (C) 1996 Mizutori Tetsuya, July 4 1996, August 4, 1996.
  4. // ==================================================
  5. //    All documents are pretty-printed in Geneva 10-point font.
  6.  
  7. #include <LPane.h>
  8. #include <LDragTask.h>
  9. #include <UDrawingState.h>
  10. #include <UDrawingUtils.h>
  11. #include <LBroadcaster.h>
  12. #include <LCommander.h>
  13.  
  14. #include <PP_Messages.h>
  15.  
  16. #include "touchMeConstants.h"
  17. #include "CTouchMeDialog.h"
  18. #include "CTouchMeDialogDD.h"
  19. #include "CDateEditField.h"
  20.  
  21. /*****
  22. enum {
  23.     flavorTypeHFS            = 'hfs ',
  24.     flavorTypePromiseHFS    = 'phfs',
  25.     flavorTypeDirectory        = 'diry'
  26. };
  27.  
  28. typedef struct HFSFlavor {
  29.     OSType                fileType;
  30.     OSType                fileCreator;
  31.     unsigned short            fdFlags;
  32.     FSSpec                fileSpec;
  33. } HFSFlavor;
  34. *****/
  35.  
  36. const PaneIDT    thePaneList[8] = {
  37.     kTmeD_CrTextEditDate, kTmeD_CrTextEditTime,
  38.     kTmeD_MdTextEditDate, kTmeD_MdTextEditTime,
  39.     kNoPaneID };
  40.  
  41.  
  42. // ==================================================
  43. //    Drag and Drop
  44. // ==================================================
  45.  
  46. // --------------------------------------------------
  47. //        ・ ItemIsAcceptable
  48. // --------------------------------------------------
  49.  
  50. Boolean
  51. CTouchMeDialog::ItemIsAcceptable(
  52.     DragReference    inDragRef,
  53.     ItemReference    inItemRef )
  54. {
  55.     Boolean        theResult = false;
  56.     FlavorFlags    theFlags;
  57.  
  58.     // Accept only HFS-type files, which are dragged from Finder.
  59.     theResult = IsEnabled() && 
  60.         ( ::GetFlavorFlags( inDragRef, inItemRef, flavorTypeHFS, &theFlags ) == noErr );
  61.  
  62.     return theResult;
  63. }
  64.  
  65.  
  66. // --------------------------------------------------
  67. //        ・ ReceiveDragItem
  68. // --------------------------------------------------
  69.  
  70. void
  71. CTouchMeDialog::ReceiveDragItem(
  72.     DragReference    inDragRef,
  73.     DragAttributes    inDragAttrs,
  74.     ItemReference    inItemRef,
  75.     Rect            &inItemBounds )
  76. {
  77. #pragma unused( inDragAttrs, inItemBounds )
  78.     OSErr        err;
  79.  
  80.     FlavorFlags    theFlags;
  81.     err = ::GetFlavorFlags( inDragRef, inItemRef, flavorTypeHFS, &theFlags );
  82.     ThrowIfOSErr_( err );
  83.  
  84.     // Get the flavor data.
  85.     HFSFlavor    theHFSFlavor;
  86.     Size        theDataSize = sizeof( HFSFlavor );
  87.     err = ::GetFlavorData( inDragRef, inItemRef,
  88.             flavorTypeHFS, (void *) &theHFSFlavor, &theDataSize, 0 );
  89.     ThrowIfOSErr_( err );
  90.  
  91.     // Get the FSSPec data from the flavor.
  92.     FSSpec    theFSSpec;
  93.     theFSSpec = theHFSFlavor.fileSpec;
  94.  
  95.     if ( mModifier ) {
  96. //    if ( IsModifierKeyPressed( inDragRef ) ) {
  97.  
  98.         // Do execute 'touch' theFSSpec, if the option-key is pressed.
  99.         ProcessCommand( cmd_Touch, (void *) &theFSSpec );
  100.  
  101.     } else {
  102.  
  103.         // Set date time EditFields by the stamp of theFSSpec, if no modifier key is pressed.
  104.         // If the file was dropped on some EditField, then the only one EditField will be changed.
  105.         // Now, get the mouse location and convert to port coordinates.
  106.         Point        thePoint;
  107.         ::GetDragMouse( inDragRef, &thePoint, nil );
  108.         GlobalToPortPoint( thePoint );
  109.  
  110.         PaneIDT    thePaneID = FindPaneByMouse( thePoint );
  111.  
  112.         switch ( thePaneID ) {
  113.             case kTmeD_CrTextEditDate:
  114.                 BroadcastMessage( msg_TmeD_DroppedFileCrDate, (void *) &theFSSpec ); break;
  115.             case kTmeD_CrTextEditTime:
  116.                 BroadcastMessage( msg_TmeD_DroppedFileCrTime, (void *) &theFSSpec ); break;
  117.             case kTmeD_MdTextEditDate:
  118.                 BroadcastMessage( msg_TmeD_DroppedFileMdDate, (void *) &theFSSpec ); break;
  119.             case kTmeD_MdTextEditTime:
  120.                 BroadcastMessage( msg_TmeD_DroppedFileMdTime, (void *) &theFSSpec ); break;
  121.             default:
  122.                 BroadcastMessage( msg_TmeD_DroppedFile, (void *) &theFSSpec ); break;
  123.         }
  124.  
  125.     }
  126. }
  127.  
  128.  
  129. // --------------------------------------------------
  130. //        ・ EnterDropArea
  131. // --------------------------------------------------
  132.  
  133. void
  134. CTouchMeDialog::EnterDropArea(
  135.     DragReference    inDragRef,
  136.     Boolean        inDragHasLeftSender )
  137. {
  138.     // Call inherited.
  139.     LDragAndDrop::EnterDropArea( inDragRef, inDragHasLeftSender );
  140.  
  141.     // Check the status of modifier keys, whether it is pressed or not.
  142.     mModifier = IsModifierKeyPressed( inDragRef );
  143.  
  144.     // Invalidate the last hilite pane.
  145.     mHilitePaneID = kNoPaneID;
  146.  
  147.     // Remember the last (latent) target before a drag & drop operation.
  148. //    mTargetID = kNoPaneID;    // This time, we do not use ID number.
  149.     mTarget = nil;
  150.  
  151.     // Get the EditField as a target commander among four EditFields.
  152.     // If the dialog is in front, then 'GetTarget()' returns the target EditField.
  153.     // If it is not in front or in background, then the dialog itself is a latent sub commander,
  154.     // so that the desired EditField is to be get by 'GetLatentSub()' of the dialog.
  155.     LCommander *        theTarget = GetTarget();
  156.     LCommander *        theLatentTarget = GetLatentSub();
  157.     if ( theLatentTarget != nil )
  158.         theTarget = theLatentTarget->GetLatentSub();
  159.  
  160.     if ( theTarget != nil ) {
  161.         // If a target exists, it must be an EditField and then should be deactivated.
  162.         // You can confirm which the target is a type of EditField, as follows.
  163.         //    PaneIDT    iPaneID, iTargetPaneID;
  164.         //    iTargetPaneID = ((CDateEditField *) theTarget)->GetPaneID();
  165.         //    Boolean    found=false;
  166.         //    for ( short i=0; (iPaneID=thePaneList[i]) != kNoPaneID; i++ )
  167.         //        if ( iTargetPaneID == iPaneID ) { found=true; }
  168.         //    if ( found ) mTargetID = iTargetPaneID;
  169.         mTarget = theTarget;
  170.         // Let's deactivate the TE field because the hilite color can be
  171.         // distinguished between colors by selection and HiliteRect().
  172.         mTEActive = ((CDateEditField *) theTarget)->GetTEActive();
  173.         ((CDateEditField *) theTarget)->SetTEActive( false );
  174.     }
  175. }
  176.  
  177.  
  178. // --------------------------------------------------
  179. //        ・ LeaveDropArea
  180. // --------------------------------------------------
  181.  
  182. void
  183. CTouchMeDialog::LeaveDropArea(
  184.     DragReference    inDragRef )
  185. {
  186.     // Check the status of modifier keys, which is pressed or not.
  187.     mModifier = false;
  188.  
  189.     // Invalidate the last hilite pane.
  190.     HilitePane( mHilitePaneID );
  191.     mHilitePaneID = kNoPaneID;
  192.  
  193.     // Restore the last (latent) target before a drag & drop operation.
  194. //    if ( mTargetID != kNoPaneID ) {    // This time, we do not use ID number.
  195.     if ( mTarget != nil ) {
  196.     //    LCommander *    theTarget = (LCommander *) FindPaneByID( mTargetID );
  197.     //    SwitchTarget( theTarget );
  198.         ((CDateEditField *) mTarget)->SetTEActive( mTEActive );
  199.     }
  200. //    mTargetID = kNoPaneID;
  201.     mTarget = nil;
  202.  
  203.     // Call inherited.
  204.     LDragAndDrop::LeaveDropArea( inDragRef );
  205. }
  206.  
  207.  
  208. // --------------------------------------------------
  209. //        ・ InsideDropArea
  210. // --------------------------------------------------
  211.  
  212. void
  213. CTouchMeDialog::InsideDropArea(
  214.     DragReference    inDragRef )
  215. {
  216.     // Call inherited.
  217.     LDragAndDrop::InsideDropArea( inDragRef );
  218.  
  219.     // If option-key is pressed, then hilite area is the bound of this dialog box.
  220. //    if ( IsModifierKeyPressed( inDragRef ) ) return;
  221.     if ( mModifier ) return;
  222.  
  223.     // Set the current port to this dialog.
  224.     if ( ! FocusDraw() )  return;
  225.  
  226.     // Get the mouse location and convert to port coordinates.
  227.     Point        thePoint;
  228.     ::GetDragMouse( inDragRef, &thePoint, nil );
  229.     GlobalToPortPoint( thePoint );
  230.  
  231.     // If dragging position is in some EditField, then the EditField turns to be hilited.
  232.     PaneIDT    thePaneID = FindPaneByMouse( thePoint );
  233.     if ( thePaneID != mHilitePaneID ) HilitePane( thePaneID );
  234. }
  235.  
  236.  
  237. // --------------------------------------------------
  238. //        ・ HiliteDropArea
  239. // --------------------------------------------------
  240.  
  241. void
  242. CTouchMeDialog::HiliteDropArea(
  243.     DragReference    inDragRef )
  244. {
  245.     RgnHandle    theHiliteRgnH = ::NewRgn();
  246.  
  247.     // I do not know why 'mModifier' is not updated as the one of 'EnterDropArea()'. ???
  248. //    if ( mModifier ) {
  249.     if ( IsModifierKeyPressed(inDragRef) ) {
  250.  
  251.         // If option-key is pressed, the hilite region is the dialog rect.
  252.         Rect        theRect;
  253.         CalcLocalFrameRect( theRect );
  254.         ::RectRgn( theHiliteRgnH, &theRect );
  255.         FocusDraw();    // 'Focus()' and 'Refresh()' seems to be required here,
  256.         Refresh();        // otherwise the 'ShowDragHilite()' does not work properly.
  257.  
  258.     } else {
  259.  
  260.         // If no modifier key is pressed, the hilite region is a union of EditFields.
  261.         RgnHandle    theRgnH = ::NewRgn();
  262.         PaneIDT    iPaneID;
  263.         // Get hilite region.
  264.         for ( short i=0;  (iPaneID=thePaneList[i]) != kNoPaneID; i++ ) {
  265.             Rect        theRect;
  266.             LPane    *thePane;
  267.             thePane = (LPane *) FindPaneByID( iPaneID );
  268.             thePane->FocusDraw();    // 'Focus()' and 'Refresh()' seems to be required here,
  269.             thePane->Refresh();        // otherwise the 'ShowDragHilite()' does not work properly.
  270.             thePane->CalcPortFrameRect( theRect );
  271.             ::RectRgn( theRgnH, &theRect );
  272.             ::UnionRgn( theHiliteRgnH, theRgnH, theHiliteRgnH );
  273.         }
  274.         ::DisposeRgn( theRgnH );
  275.  
  276.     }
  277.  
  278.     ::ShowDragHilite( inDragRef, theHiliteRgnH, true );
  279.  
  280.     ::DisposeRgn( theHiliteRgnH );
  281. }
  282.  
  283.  
  284. // ==================================================
  285. //    Common functions
  286. // ==================================================
  287.  
  288. // --------------------------------------------------
  289. //        ・ IsModifierKeyPressed
  290. // --------------------------------------------------
  291.  
  292. Boolean
  293. CTouchMeDialog::IsModifierKeyPressed(
  294.     DragReference    inDragRef )
  295. {
  296.     short        theModifiers, theMouseDownModifiers, theMouseUpModifiers;
  297.  
  298.     ::GetDragModifiers( inDragRef,
  299.         &theModifiers, &theMouseDownModifiers, &theMouseUpModifiers );
  300.  
  301.     return (Boolean) ( (theModifiers & optionKey ) != 0 );
  302. }
  303.  
  304.  
  305. // --------------------------------------------------
  306. //        ・ FindPaneByMouse
  307. // --------------------------------------------------
  308.  
  309. PaneIDT
  310. CTouchMeDialog::FindPaneByMouse(
  311.     const Point        inPoint )
  312. {
  313.     PaneIDT    iPaneID;
  314.  
  315.     for ( short i=0;  (iPaneID=thePaneList[i]) != kNoPaneID; i++ ) {
  316.         Rect        theRect;
  317.         LPane    *thePane;
  318.         thePane = (LPane *) FindPaneByID( iPaneID );
  319.         thePane->CalcPortFrameRect( theRect );
  320.         if ( ::PtInRect( inPoint, &theRect ) ) return iPaneID;
  321.     }
  322.  
  323.     return (PaneIDT) kNoPaneID;
  324. }
  325.  
  326.  
  327. // --------------------------------------------------
  328. //        ・ HilitePane
  329. // --------------------------------------------------
  330.  
  331. void
  332. CTouchMeDialog::HilitePane(
  333.     const PaneIDT        inPaneID )
  334. {
  335.     // Set the current port to this dialog.
  336.     if ( ! FocusDraw() ) return;
  337.  
  338.     // Restore the previous one.
  339.     if ( mHilitePaneID != kNoPaneID ) {
  340.         LPane *    thePane = (LPane *) FindPaneByID( mHilitePaneID );
  341.         Rect        theRect;
  342.         thePane->CalcPortFrameRect( theRect );
  343.         HiliteRect( theRect );
  344.     }
  345.  
  346.     if ( inPaneID == mHilitePaneID ) return;
  347.  
  348.     // Setup the present one.
  349.     if ( inPaneID != kNoPaneID ) {
  350.         LPane *    thePane = (LPane *) FindPaneByID( inPaneID );
  351.         Rect        theRect;
  352.         thePane->CalcPortFrameRect( theRect );
  353.         HiliteRect( theRect );
  354.     } 
  355.  
  356.     mHilitePaneID = inPaneID;
  357. }
  358.  
  359.  
  360. // --------------------------------------------------
  361. //        ・ HiliteRect
  362. // --------------------------------------------------
  363. #include <LowMem.h>
  364.  
  365. void
  366. CTouchMeDialog::HiliteRect(
  367.     const Rect &    inRect )
  368. {
  369.     // From "Highlighting" section in p.4-41,
  370.     // Apple Computer's Inside Macintosh "Imaging with QuickDraw".
  371.  
  372.     UInt8    theHiliteMode;
  373.     theHiliteMode = ::LMGetHiliteMode();
  374. //    theHiliteMode &= ~( (UInt8) 0x01 << hiliteBit );
  375.     ::BitClr( &theHiliteMode, pHiliteBit );
  376.     ::LMSetHiliteMode( theHiliteMode );
  377.  
  378.     ::InvertRect( &inRect );
  379. }
  380.  
  381.  
  382. // --------------------------------------------------
  383. //        ・ Indicator
  384. // --------------------------------------------------
  385. // I prefer to show a very tiny spot at the corner to indicate the status.
  386.  
  387. void
  388. CTouchMeDialog::Indicator(
  389.     const Boolean    inStatus )
  390. {
  391.     static Boolean    gStatus = false;
  392.  
  393.     if ( inStatus != gStatus && FocusDraw() ) {
  394.         Rect        theRect;
  395.         ::SetRect( &theRect, 3, 3, 8, 8 );    // (left,top,right,bottom)
  396.         if ( inStatus ) ::FillRect( &theRect, &(qd.gray) );
  397.         else ::EraseRect( &theRect );
  398.     }
  399.  
  400.     gStatus = inStatus;
  401. }
  402.  
  403. // end of program
  404.